//package com.geely.pma.climate.api.observation
package com.wanghaibo.vgashow.api.observation;


import com.ecarx.xui.adaptapi.FunctionStatus
import com.ecarx.xui.adaptapi.car.base.ICarFunction
import com.ecarx.xui.adaptapi.car.base.ICarFunction.IFunctionValueWatcher
import java.util.*

/**
 * Name: CarFunctionObservationManager
 *
 * Created by Wuhao on 2019/12/20
 *
 * Version: 0.0.1
 */
class CarFunctionObservationManager(// if function is null, means that register all functions
    private val function: Int?
) : ICarFunctionSubscription {

    private val observations: MutableList<CarFunctionObservation> = ArrayList()

    override fun observeFunction(carFunction: ICarFunction, observation: CarFunctionObservation) {
        synchronized(observations) {
            observations.add(observation)
            if (observations.size == 1) {
                registerWatcher(carFunction)
            }
        }
    }

    private fun registerWatcher(carFunction: ICarFunction) {
        if (function == null) {
            carFunction.registerFunctionValueWatcher(underlyingWatcher)
        } else {
            carFunction.registerFunctionValueWatcher(function, underlyingWatcher)
        }
    }

    fun forceRegister(carFunction: ICarFunction) {
        if (observations.size > 0) {
            registerWatcher(carFunction)
        }
    }

    fun removeIFunctionValueWatcher(carFunction: ICarFunction, watcher: IFunctionValueWatcher) {
        synchronized(observations) {
            var existing = false
            val iterator = observations.iterator()
            while (iterator.hasNext()) {
                val next = iterator.next()
                if (next.callerWatcher == watcher) {
                    existing = true
                    iterator.remove()
                }
            }
            if (existing && observations.isEmpty()) {
                carFunction.unregisterFunctionValueWatcher(underlyingWatcher)
            }
        }
    }

    fun clear(carFunction: ICarFunction) {
        synchronized(observations) {
            observations.clear()
            carFunction.unregisterFunctionValueWatcher(underlyingWatcher)
        }
    }

    private val underlyingWatcher: IFunctionValueWatcher = object : IFunctionValueWatcher {
        override fun onFunctionChanged(function: Int) {
            // not observed now
        }

        override fun onFunctionValueChanged(function: Int, zone: Int, value: Int) {
            for (observation in observations.toTypedArray()) {
                observation.onFunctionValueChanged(function, zone, value)
            }
        }

        override fun onCustomizeFunctionValueChanged(function: Int, zone: Int, value: Float) {
            for (observation in observations.toTypedArray()) {
                observation.onCustomizeFunctionValueChanged(function, zone, value)
            }
        }

        override fun onSupportedFunctionStatusChanged(
            function: Int, zone: Int, status: FunctionStatus
        ) {
            for (observation in observations.toTypedArray()) {
                observation.onSupportedFunctionStatusChanged(function, zone, status)
            }
        }

        override fun onSupportedFunctionValueChanged(function: Int, funcValues: IntArray) {
            // not observed now
        }
    }
}